package com.ecoolex.ying.space.core.manager;

import com.ecoolex.framework.common.enums.ResultCode;
import com.ecoolex.framework.common.pojo.Page;
import com.ecoolex.framework.common.pojo.Pagination;
import com.ecoolex.framework.common.pojo.Sorting;
import com.ecoolex.framework.common.pojo.Sortings;
import com.ecoolex.framework.common.util.BizAssert;
import com.ecoolex.framework.common.util.Check;
import com.ecoolex.ying.space.core.dao.GoodsLabelDAO;
import com.ecoolex.ying.space.core.service.PickGoodsSearchService;
import com.ecoolex.ying.space.entity.GoodsLabel;
import com.ecoolex.ying.space.entity.GoodsLabel.Column;
import com.ecoolex.ying.space.entity.GoodsLabelExample;
import com.ecoolex.ying.space.pojo.QueryGoodsLabelDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Instant;
import java.util.Date;
import java.util.List;

@Service
public class GoodsLabelManager {
    @Autowired
    private GoodsLabelDAO dao;

    @Autowired
    private GoodsLabelAssociateManager goodsLabelAssociateManager;
    @Autowired
    private PickGoodsLabelAssociateManager pickGoodsLabelAssociateManager;

    @Autowired
    private PickGoodsSearchService pickGoodsSearchService;

    private void verify(GoodsLabel record) {
        BizAssert.isTrue(Check.notNullOrTrimEmpty(record.getName()), ResultCode.VERIFY.build(10), "标签名称不能为空");
    }

    public GoodsLabel create(GoodsLabel record, String createUser) {
        verify(record);

        record.setDeleted(GoodsLabel.NOT_DELETED);
        record.setCreateUser(createUser);
        record.setCreateTime(Date.from(Instant.now()));
        record.setUpdateUser(createUser);
        record.setUpdateTime(Date.from(Instant.now()));
        dao.insert(record);
        return record;
    }

    @Transactional
    public void update(GoodsLabel record, String updateUser) {
        verify(record);

        GoodsLabel old = getById(record.getLabelId());

        record.setUpdateUser(updateUser);
        record.setUpdateTime(Date.from(Instant.now()));
        int row = dao.updateByPrimaryKeySelective(record,
                Column.excludes(Column.deleted,
                        Column.createUser,
                        Column.createTime));
        BizAssert.isTrue(row == 1, "编辑标签失败");

        pickGoodsSearchService.changeLabel(old, record);
    }

    @Transactional
    public void delete(GoodsLabel record, String updateUser) {
        // check
        long countGoodsUsedNumber = goodsLabelAssociateManager.countByLabelId(record.getLabelId());
        BizAssert.isTrue(countGoodsUsedNumber == 0,
                ResultCode.VERIFY.build(10),
                "该标签还存在{}个商品正在使用",
                countGoodsUsedNumber);
        long countPickGoodsUserdNumber = pickGoodsLabelAssociateManager.countByLabelId(record.getLabelId());
        BizAssert.isTrue(countPickGoodsUserdNumber == 0,
                ResultCode.VERIFY.build(11),
                "该标签还存在{}个优选商品正在使用",
                countPickGoodsUserdNumber);

        record.setDeleted(GoodsLabel.IS_DELETED);
        record.setUpdateUser(updateUser);
        record.setUpdateTime(Date.from(Instant.now()));
        dao.updateByPrimaryKeySelective(record,
                Column.deleted,
                Column.updateUser,
                Column.updateTime);
    }

    public GoodsLabel getById(Integer labelId) {
        return dao.selectByPrimaryKeyWithLogicalDelete(labelId, GoodsLabel.NOT_DELETED);
    }

    public List<GoodsLabel> queryAll() {
        GoodsLabelExample example = new GoodsLabelExample();
        GoodsLabelExample.Criteria criteria = example.createCriteria();

        criteria.andDeletedEqualTo(GoodsLabel.NOT_DELETED);

        return dao.selectByExample(example);
    }

    public List<GoodsLabel> query(QueryGoodsLabelDTO query, Integer maxSize) {
        GoodsLabelExample example = new GoodsLabelExample();
        GoodsLabelExample.Criteria criteria = example.createCriteria();

        if (Check.notNullOrTrimEmpty(query.getName())) {
            criteria.andNameLike('%' + query.getName() + '%');
        }

        criteria.andDeletedEqualTo(GoodsLabel.NOT_DELETED);

        example.limit(maxSize);
        return dao.selectByExample(example);
    }

    public Pagination<GoodsLabel> query(QueryGoodsLabelDTO query, Sorting[] sorts, Page page) {
        GoodsLabelExample example = new GoodsLabelExample();
        GoodsLabelExample.Criteria criteria = example.createCriteria();

        if (Check.notNullOrTrimEmpty(query.getName())) {
            criteria.andNameLike('%' + query.getName() + '%');
        }

        criteria.andDeletedEqualTo(GoodsLabel.NOT_DELETED);

        example.orderBy(Sortings.builder(sorts).verify(Column::valueOf).toSql());
        example.setOffset(page.getFirstIndex());
        example.setRows(page.getPageSize());

        return Pagination.create(page, dao.countByExample(example), ()-> dao.selectByExample(example));
    }

    public List<GoodsLabel> queryByGoodsId(Integer goodsId) {
        return dao.queryByGoodsId(goodsId);
    }

    public List<GoodsLabel> queryByPickGoodsId(Integer pickGoodsId) {
        return dao.queryByPickGoodsId(pickGoodsId);
    }
}